#include "main.h"

namespace rv = ::std::ranges::views;
using namespace ::std::chrono_literals;
using namespace ::std::string_view_literals;
using namespace wilson;

sys::thread_pool<sys::normal_task_mgr, coro::epoll_sleeper>* p;
coro::epoll_suspend_manager* esm_p;

static bool threads_flag_validator(const char* flagname, int32_t val)
{
    if (val >= 1) return true;
    fmt::print("{}","Usage: app --threads <threads_count>\n");
    return false;
}

DEFINE_int32(threads, 10, "How many threads running with");
DEFINE_validator(threads, &threads_flag_validator);

coro::task<int> task2()
{
    static ::std::atomic_int i{1};
    //WILSON_LOG_DEBUG(fmt::format("call task2 {} time(s)", i));
    co_return i++;
}

coro::task<void> start1()
{
    for (int i = 0; i < 100; ++i)
    {
        int j = co_await schedule_aw(*p, task2());
        WILSON_LOG_DEBUG(fmt::format("{}", j));
    }
    co_return;
}

void coro_basic_test()
{
    size_t thrcnt = FLAGS_threads;
    coro::epoll_suspend_manager esm{ thrcnt };
    sys::timerbase timer{};
    coro::epoll_sleeper es{ esm, timer };
    sys::thread_pool<sys::normal_task_mgr, coro::epoll_sleeper> tp{
        thrcnt, es
    };
    esm_p = &esm;
    p = &tp;
    coro::sleeping_suspend_manager<decltype(tp)> ssm{ timer, tp };

    for (int i = 0; i < 100; ++i)
        schedule(tp, start1());

    tp.stop();
    tp.join();
}

void coro_relate_tests()
{
    size_t thrcnt = FLAGS_threads;
    coro::epoll_suspend_manager esm{ thrcnt };
    sys::timerbase timer{};
    coro::epoll_sleeper es{ esm, timer };
    sys::thread_pool<sys::normal_task_mgr, coro::epoll_sleeper> tp{
        thrcnt, es
    };
    esm_p = &esm;
    p = &tp;
    coro::sleeping_suspend_manager<decltype(tp)> ssm{ timer, tp };

    // http test==============
    
    net::ipv4_address addr{ 127,0,0,1 };
    http::http_server hs{ tp, addr, 8890 };
    hs.set_callback([](auto httpc)->coro::task<void>{
        ::std::error_code ec;
        auto req = co_await httpc.recv_request(ec);
        if (ec) co_return;

        http::server::response_builder respb;
        respb.set_status(http::status::OK);
        respb.set_version(req.get_version());
        ::std::string_view body{ "<html>ok</html>" };
        respb.set_header("Content-Type", util::get_mime_type("xx.html"sv));
        respb.set_header("Content-Length", ::std::to_string(body.size()));
        respb.set_body(body);

        auto resp = respb.generate_response();

        ec.clear();
        co_await httpc.send_response(resp, ec);
        
        co_return;
    });
    hs.start();

    // =======================
   
    tp.join();
}

using namespace wilson;

DEFINE_string(loglevel, "debug", "How many threads running with");
DEFINE_validator(loglevel, [](const char* filename, const ::std::string& val) {
    if (val != "debug" && val != "info") return false;
    return true;
});
DEFINE_int32(sleep, 0, "sleep for [] secs before execute");
DEFINE_validator(sleep, [](const char* filename, int32_t val) {
    if (val < 0) return false;
    return true;
});

int main(int argc, char** argv)
{
    //gflags::ParseCommandLineFlags(&argc, &argv, true);
    ////::signal(SIGINT, sigint_handler);
    //
    //util::log_init(FLAGS_loglevel);
    //auto slpfor = ::std::chrono::seconds{ FLAGS_sleep };
    //WILSON_LOG_DEBUG(
    //    fmt::format("OK, threads = {}, loglevel = {}. sleep for {} SECs.", 
    //        FLAGS_threads, FLAGS_loglevel, slpfor.count()));
    //::std::this_thread::sleep_for(slpfor);
    //
    //coro_relate_tests();
    ////coro_basic_test();
    
    return 0;
}
